package com.xmh.ssm.utils.reptile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import com.xmh.ssm.dao.SexVideoDAO;
import com.xmh.ssm.other.HtmlUtil;
import com.xmh.ssm.vo.SexVideoEntity;

//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("/spring_bean.xml")
//@Transactional
public class SexReptile {

	private final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private SexVideoDAO dao;

	@Autowired
	private ThreadPoolTaskExecutor poolTaskExecutor;

	private final ExecutorService executorService = Executors.newCachedThreadPool();

	final WebClient webClient = new WebClient(BrowserVersion.CHROME);// 新建一个模拟谷歌Chrome浏览器的浏览器客户端对象

	@Test
	public void main() throws IOException, InterruptedException {

		webClient.getOptions().setThrowExceptionOnScriptError(false);// 当JS执行出错的时候是否抛出异常, 这里选择不需要
		webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);// 当HTTP的状态非200时是否抛出异常, 这里选择不需要
		webClient.getOptions().setActiveXNative(false);
		webClient.getOptions().setCssEnabled(false);// 是否启用CSS, 因为不需要展现页面, 所以不需要启用
		webClient.getOptions().setJavaScriptEnabled(true); // 很重要，启用JS
		webClient.setJavaScriptEngine(new MyJavaScriptEngine(webClient));// 自定义JavaScript引擎，有js错误不打印
		webClient.setAjaxController(new NicelyResynchronizingAjaxController());// 很重要，设置支持AJAX

		try {
			webClient.getPage("https://sssjj3.com/video/detail/230613?ccc=3yyyuu.com");
		} catch (Exception e) {
			e.printStackTrace();
		}

		webClient.waitForBackgroundJavaScript(3000);// 异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束

		String homeUrl = "https://sssjj3.com/video/monthly-ranking?page=";

		for (int i = 1; i <= 8; i++) {
			String url = homeUrl + i;

			Document document = Jsoup.connect(url).get();

			Iterator<Element> iterator = document.select("div[class='pure-u-1 thumbnail'] > a[target='_blank']")
					.iterator();
			while (iterator.hasNext()) {
				Element element = iterator.next();
				String attr = element.attr("href");

				String substringBetween = StringUtils.substringBetween(attr, "detail/", "#");

				String urlString = "https://sssjj3.com/video/detail/" + substringBetween + "#header";

				HtmlPage page = webClient.getPage(urlString);

				long timeoutMillis = 3000L;

				webClient.waitForBackgroundJavaScript(timeoutMillis);// 异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束

				String pageXml = page.asXml();

				if (!pageXml.contains("var video = document.getElementById('video');")) {
					HtmlForm form = page.getForms().get(0);
					HtmlTextInput txtUName = (HtmlTextInput) form.getInputByName("c1"); //
					txtUName.setValueAttribute("0118659813");

					HtmlTextInput txtPwd = (HtmlTextInput) form.getInputByName("c2");// 密码框
					txtPwd.setValueAttribute("1908282238");

					form.getButtonByName("").click();

					webClient.waitForBackgroundJavaScript(timeoutMillis);// 等待1秒

					page = webClient.getPage(urlString);

					webClient.waitForBackgroundJavaScript(timeoutMillis);// 异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束

					pageXml = page.asXml();
				}
				String downId = StringUtils.substringBetween(pageXml, "hls.loadSource(\"/cdn/vip/hls/", ".");

				String lodTiele = Jsoup.parse(pageXml).getElementById("title").text();

				String title = lodTiele.replace("/", "_").replace(" ", "_");

				poolTaskExecutor.execute(() -> {
					Future<String> future = executorService.submit(() -> {
						downloadZip(downId, lodTiele);
						return "sueecs";
					});
					try {
						// 设置超时时间
						future.get(60L * 60L * 3L, TimeUnit.SECONDS);
					} catch (Exception e) {
						future.cancel(true);

						logger.error("");
						logger.error("====================== 下载超时 ==========================");
						logger.error("标题：" + title);
						logger.error(e);
						logger.error("");

						String pathname = "I:\\download\\" + title;
						String downloadUrl = "https://sssjj3.com/cdn/xx/file/" + downId + "/";

						new File(pathname).delete();

						SexVideoEntity entity = new SexVideoEntity();
						entity.setTitle(title);
						entity.setPath(pathname);
						entity.setUrl(downloadUrl);
						Integer valueOf = Integer.valueOf(downId);
						entity.setDownid(valueOf);
						entity.setState(false);
						dao.add(entity);
					}
				});

				Thread.sleep(timeoutMillis);
			}
		}
		Thread.sleep(1000L * 60L * 60L * 24L * 3L);
	}

	private void downloadZip(String downId, String lodTiele) {
		String title = lodTiele.replace("/", "_").replace(" ", "_");

//		String downloadUrl = getDownloadUrl(lodTiele, downId);
		String downloadUrl = "https://sssjj3.com/cdn/xx/file/" + downId + "/";

		String pathname = "I:\\download\\" + title;

		SexVideoEntity entity = new SexVideoEntity();
		entity.setTitle(title);
		entity.setPath(pathname);
		entity.setUrl(downloadUrl);
		Integer valueOf = Integer.valueOf(downId);
		entity.setDownid(valueOf);

		SexVideoEntity sexVideoEntity = dao.get(new SexVideoEntity(valueOf));
		if (sexVideoEntity != null) {
			if (sexVideoEntity.getState()) {
				logger.info("====================== 已存在==========================");
				return;
			}
			dao.delete(sexVideoEntity);
		}
		System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2,SSLv3");
		logger.info("");
		logger.info("====================== 下载开始==========================");
		logger.info("标题：" + title);
		logger.info("地址：" + downloadUrl);
		logger.info("");
		File file = new File(pathname);
		FileOutputStream fileOutputStream = null;
		InputStream inputStream = null;
		try {
			fileOutputStream = new FileOutputStream(file);

			URL url = new URL(downloadUrl);

			URLConnection connection = url.openConnection();

			inputStream = connection.getInputStream();

			int length = 0;
			byte[] bytes = new byte[1024];
			while ((length = inputStream.read(bytes)) != -1) {
				fileOutputStream.write(bytes, 0, length);
			}
			fileOutputStream.close();
			inputStream.close();

			entity.setState(true);
			dao.add(entity);
			logger.info("");
			logger.info("======================下载完成==========================");
			logger.info("标题：" + title);
			logger.info("");
		} catch (IOException e) {
			entity.setState(false);
			dao.add(entity);
			logger.error("======================下载报错==========================");
			logger.error("标题：" + title);
			logger.error("地址：" + downloadUrl);
			logger.error(e);
			try {
				if (fileOutputStream != null) {
					fileOutputStream.close();
				}
				if (inputStream != null) {
					inputStream.close();
				}
			} catch (IOException e1) {
				logger.error(e1);
			}
			file.delete();
		}
	}

	public String getDownloadUrl(String title, String downId) {
		try {
			String titleEncode = URLEncoder.encode(title, "utf8").replace("+", "%20");

			int x = 15;
			int y = 6;

			return "https://x" + x + "y" + y + ".qq360cn.com/xx/file/" + downId + "/" + titleEncode;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public int getRandom(int min, int max) {
		Random ra = new Random();
		int x = ra.nextInt(max + 1 - min) + min;
		return x;
	}

	private void page(String url) {
		final WebClient webClient = new WebClient(BrowserVersion.CHROME);// 新建一个模拟谷歌Chrome浏览器的浏览器客户端对象

		webClient.getOptions().setThrowExceptionOnScriptError(false);// 当JS执行出错的时候是否抛出异常, 这里选择不需要
		webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);// 当HTTP的状态非200时是否抛出异常, 这里选择不需要
		webClient.getOptions().setActiveXNative(false);
		webClient.getOptions().setCssEnabled(false);// 是否启用CSS, 因为不需要展现页面, 所以不需要启用
		webClient.getOptions().setJavaScriptEnabled(true); // 很重要，启用JS
		webClient.setAjaxController(new NicelyResynchronizingAjaxController());// 很重要，设置支持AJAX

		HtmlPage page = null;
		try {
			page = webClient.getPage("http://ent.sina.com.cn/film/");// 尝试加载上面图片例子给出的网页
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			webClient.close();
		}

		webClient.waitForBackgroundJavaScript(30000);// 异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束

		String pageXml = page.asXml();// 直接将加载完成的页面转换成xml格式的字符串

		// TODO 下面的代码就是对字符串的操作了,常规的爬虫操作,用到了比较好用的Jsoup库

		Document document = Jsoup.parse(pageXml);// 获取html文档
		List<Element> infoListEle = document.getElementById("feedCardContent").getElementsByAttributeValue("class",
				"feed-card-item");// 获取元素节点等
		infoListEle.forEach(element -> {
			System.out.println(element.getElementsByTag("h2").first().getElementsByTag("a").text());
			System.out.println(element.getElementsByTag("h2").first().getElementsByTag("a").attr("href"));
		});
	}

	@Test
	public void test2() throws IOException, InterruptedException {
		poolTaskExecutor.execute(() -> {
			System.out.println("1");
			String url = "http://localhost:8080/userPayController/selectList?amnout=9";

			String doGet = HtmlUtil.doGet(url);

			System.out.println("2");
			System.out.println(doGet);
		});

//		ExecutorService executor = Executors.newSingleThreadExecutor();
//		Callable<Result> work = new Callable<Result>() {
//		    @Override
//		    public Result call() {
//		        // do something
//		        return  result
//		    }
//		};
//		Future<Result> future = executor.submit(work);
//		try {
//		    result = future.get(TIMEOUT, TIMEUNIT); 
//		} catch (TimeoutException e) { 
//		    ...
//		} catch (...) {
//		    ...
//		}

		Thread.sleep(10000);
	}

	@Test
	public void test3() throws InterruptedException {
		try {
			runWithTimeout(() -> {
				while (true)
					System.out.println("运行中············");
			}, 1, TimeUnit.SECONDS);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("结束1");
		Thread.sleep(2000L);
		System.out.println("结束2");
	}

	public void runWithTimeout(final Runnable runnable, long timeout, TimeUnit timeUnit) throws Exception {
		runWithTimeout(() -> {
			runnable.run();
			return null;
		}, timeout, timeUnit);
	}

	public <T> T runWithTimeout(Callable<T> callable, long timeout, TimeUnit timeUnit) throws Exception {
//		final ExecutorService executor = Executors.newSingleThreadExecutor();
//		final Future<T> future = executor.submit(callable);
		Future<T> future = poolTaskExecutor.submit(callable);
		try {
			return future.get(timeout, timeUnit);
		} catch (Exception e) {
			future.cancel(true);
			throw e;
		}
	}

	@Test
	public void test4() {
		List<SexVideoEntity> selectList = dao.selectList(new HashMap<String, Object>());

		for (SexVideoEntity sexVideoEntity : selectList) {
			File file = new File(sexVideoEntity.getPath());

			File newName = new File("I:\\共享文件夹\\SexVideo\\" + sexVideoEntity.getTitle());

			file.renameTo(newName);
		}

	}

	@Test
	public void test5() throws UnsupportedEncodingException {
		String string = "jux00634 家庭乱伦 親父の女 本田岬.mp4";

		String urlString = "https://x2y3.qq360cn.com/xx/file/887373/" + string;

//		String encode = System.out.println(encode);
	}

}
